﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;

namespace HttpPackage
{
    public class HttpTcpClient : IHttp
    {
        private TcpClient _tcpClient;
        //private string _addresse;
        private int _port = 80;
        private int _timeout;

        public HttpTcpClient()
        {
            _tcpClient = new TcpClient(AddressFamily.InterNetwork);
            _tcpClient.ReceiveTimeout = 10000;
            _tcpClient.SendTimeout = 10000;
        }

        public HttpTcpClient(string uri) 
            : this()
        {
            Open(uri);
        }

        public bool IsConnected
        {
            get { return _tcpClient.Connected; }
        }

       
         public int TimeOut
        {
            get { return _timeout; }
            set
            { 
                _timeout = value;
                _tcpClient.ReceiveTimeout = value;
                _tcpClient.SendTimeout = value;
            }
        }

        public void Open(string url)
        {
            _tcpClient.Connect(url, _port);
        }

        public void Close()
        {
            _tcpClient.Close();
        }

        public void Send(string command)
        {
            // Get the networkstream to send command to the server
            NetworkStream stream = _tcpClient.GetStream();

            // Translate string to byte array
            Byte[] data = System.Text.Encoding.ASCII.GetBytes(command);

            // Send command to web server
            stream.Write(data, 0, data.Length);
        }

        public string Receive()
        {
            // Get the networkstream object to read the response
            NetworkStream stream = _tcpClient.GetStream();

            // Create databuffer for storing the response
            Byte[] data = new Byte[256];

            // String to store ASCII presentation of response
            String responseData = string.Empty;

            // read and store the response
            Int32 bytes = 0;

            // Wait counters for receiving data, waits up to 1000ms to receive data, if no data is available
            // in that time the loop will exit
            int waitTime = 1000;
            int waitCounter = 0;
            int incrementWait = 50;
            
            // the while loop takes a minimum of 1 second to execute, this could probably be optmized
            while (waitCounter < waitTime)
            {
                // check to see if data is available
                if (stream.DataAvailable)
                {
                    // read the datachunk
                    bytes = stream.Read(data, 0, data.Length);
                    responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                    // reset the counter so we can wait up to 1000ms for the next data chunk
                    waitCounter = 0;
                }
                // Sleep for 50 ms to wait for the server to send data
                Thread.Sleep(incrementWait);
                // Increment the wait counter
                waitCounter += incrementWait;
                
            }
            // Return the response data
            return responseData;
        }

        // Returns the networkstream
        public System.IO.Stream GetStream()
        {
            return _tcpClient.GetStream();
        }


        public string ConnectionTest(string url)
        {
            // Create new client for the connection
            HttpTcpClient client = new HttpTcpClient(url);

            // Send command to server (we don't know what the f it does)
            client.Send("GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: Close\r\n\r\n");

            // Get the response from the server
            string response = client.Receive();
            
            // Close connection to server
            client.Close();

            // return the response
            return response;
        }

        private void Open()
        {
            throw new NotImplementedException();
        }
    }
}
